﻿#region Imports
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows.Forms;
using CommonUtilities.Extensions;
#endregion

namespace CommonUtilities.Util
{
    /// <summary>
    /// Value Wrapper for binding against IEnumerable of structs
    /// <para>e.g.: Use 'CommonUtilities.Util.SingletonValueWrapper.ConvertToSingletonValueWrapper(IEnumerable&lt;object&gt; orgCollection)' for conversion</para>
    /// </summary>
    public class SingletonValueWrapper<TSource>
    {
        #region Properties
        /// <summary>
        /// Singleton value
        /// </summary>
        public TSource SingletonValue { get; set; }
        #endregion

        #region Methods
        /// <summary>
        /// Converts a collection of structs into a collection of a class 
        /// having the value of the struct assigned to the singleton property for binding to a control
        /// </summary>
        /// <param name="orgCollection">Original collection</param>
        /// <returns>A collection of SingletonValueWrapper with the value of the structs assigned to the singleton property</returns>
        public static IEnumerable<SingletonValueWrapper<TSource>> ConvertToSingletonValueWrapper(IEnumerable<TSource> orgCollection)
        {
            IEnumerable<SingletonValueWrapper<TSource>> finalColl = new ObservableCollection<SingletonValueWrapper<TSource>>();
            if (orgCollection.IsLinqIterable<TSource>(true))
                finalColl = orgCollection.Distinct().Select(val =>
                    new SingletonValueWrapper<TSource>
                    {
                        SingletonValue = val.ChangeType<TSource>()
                    }).AsEnumerable<SingletonValueWrapper<TSource>>();

            return finalColl;
        }

        /// <summary>
        /// Binds data to a list-based control (ListBox/ComboBox)
        /// </summary>
        /// <param name="orgCollection">Original collection</param>
        /// <param name="control">Control to bind to</param>
        public static void BindToControl(IEnumerable<TSource> orgCollection, ListControl control)
        {
            ObservableCollection<SingletonValueWrapper<TSource>> singletonCollection
                = ConvertToSingletonValueWrapper(orgCollection).ToObservableCollection();
            BindToControl(singletonCollection, control);
        }

        /// <summary>
        /// Binds data to a list-based control (ListBox/ComboBox)
        /// </summary>
        /// <param name="orgCollection">Original collection</param>
        /// <param name="control">Control to bind to</param>
        public static void BindToControl(IEnumerable<SingletonValueWrapper<TSource>> orgCollection, ListControl control)
        {
            control.DataSource = orgCollection;
            control.DisplayMember = control.ValueMember = "SingletonValue";
        }

        public override string ToString()
        {
            return Utilities.ToString(this);
        }
        #endregion
    }
}
